﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using System.IO;
using System.Drawing;

using Kooboo.Web.Mvc;

namespace Kooboo.Web.Areas.Commerce.Controllers
{
    using Kooboo.Commerce;
    using System.Security.Permissions;
    using Kooboo.Commerce.Contexts.ShopSettings;

    [FileIOPermission(SecurityAction.Demand)]
    public class ImageController : Controller
    {
        //
        // GET: /Commerce/Image/

        public ActionResult Index()
        {
            return View();
        }

        public virtual ActionResult Upload(string folder, bool isOverwrite)
        {
            try
            {
                var image = ReadImage(Request.Files["Filedata"]);

                var extension = Path.GetExtension(Request.Files["Filedata"].FileName);

                var fileName = Request.Form["Name"];

                var host = new ServiceHost();
                var settings = host.GetShopSettings();

                var root = HttpContext.Server.MapPath(Configuration.AppRootPath) + Configuration.ImageFolderName + "\\" + folder + "\\";

                var orignalName = SaveImage(image, fileName, extension, root, isOverwrite);

                var thubmail = ScaleImage(image, (int)settings.ImageSettings.Thumbnail.Width, (int)settings.ImageSettings.Thumbnail.Height);

                var thubmailName = SaveImage(thubmail, fileName, extension, root + settings.ImageSettings.Thumbnail.Name, isOverwrite);

                var detail = ScaleImage(image, (int)settings.ImageSettings.Detail.Width, (int)settings.ImageSettings.Detail.Height);

                var detailName = SaveImage(detail, fileName, extension, root + settings.ImageSettings.Detail.Name, isOverwrite);

                var list = ScaleImage(image, (int)settings.ImageSettings.List.Width, (int)settings.ImageSettings.List.Height);

                SaveImage(list, fileName, extension, root + settings.ImageSettings.List.Name, isOverwrite);

                var cart = ScaleImage(image, (int)settings.ImageSettings.Cart.Width, (int)settings.ImageSettings.Cart.Height);

                SaveImage(cart, fileName, extension, root + settings.ImageSettings.Cart.Name, isOverwrite);

                foreach (var size in settings.ImageSettings.CustomSizes)
                {
                    var item = ScaleImage(image, (int)size.Width, (int)size.Height);
                    SaveImage(cart, fileName, extension, root + size.Name, isOverwrite);
                }
                this.Response.StatusCode = 200;

                return Json(new { ThumbnailName = ResolveClientUrl(thubmailName), DetailName = ResolveClientUrl(detailName) });
                //return new UrlResult(thubmailName);
            }
            catch
            {
                // If any kind of error occurs return a 500 Internal Server error
                this.Response.StatusCode = 500;
                return Content("An error occured");
            }
        }

        Image ScaleImage(Image source, int width, int height)
        {
            System.Drawing.Bitmap finalImage = null;
            System.Drawing.Graphics graphic = null;

            // Calculate the new width and height            
            int source_width = source.Width;
            int source_height = source.Height;
            int newWidth, newHeight;

            float targetRatio = (float)width / (float)height;
            float imageRatio = (float)source_width / (float)source_height;

            if (targetRatio > imageRatio)
            {
                newHeight = height;
                newWidth = (int)Math.Floor(imageRatio * (float)height);
            }
            else
            {
                newHeight = (int)Math.Floor((float)width / imageRatio);
                newWidth = width;
            }

            newWidth = newWidth > width ? width : newWidth;
            newHeight = newHeight > height ? height : newHeight;


            finalImage = new System.Drawing.Bitmap(width, height);
            graphic = System.Drawing.Graphics.FromImage(finalImage);
            using (var solidBrush = new System.Drawing.SolidBrush(Color.Transparent))
            {
                graphic.FillRectangle(solidBrush, new System.Drawing.Rectangle(0, 0, width, height));
            }
            int paste_x = (width - newWidth) / 2;
            int paste_y = (height - newHeight) / 2;
            graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            graphic.Clear(Color.Transparent);

            graphic.DrawImage(source, paste_x, paste_y, newWidth, newHeight);


            return finalImage;
        }

        Image ReadImage(HttpPostedFileBase file)
        {
            return System.Drawing.Image.FromStream(file.InputStream);
        }

        string SaveImage(Image image, string fileName, string extension, string folder, bool isOverwrite = false)
        {

            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }

            var finalFileName = fileName + extension;

            var path = Path.Combine(folder, finalFileName);

            if (System.IO.File.Exists(path) && isOverwrite == false)
            {
                var index = Directory.GetFiles(folder).Where(n => n.ToLowerInvariant().StartsWith(finalFileName.ToLowerInvariant())).Count() + 1;
                for (var i = index; i < int.MaxValue; i++)
                {
                    finalFileName = fileName + "-" + i.ToString() + extension;
                    path = Path.Combine(folder, finalFileName);
                    if (System.IO.File.Exists(path) == false)
                    {
                        break;
                    }
                }
            }

            image.Save(path);

            return path;
        }

        private String ResolveClientUrl(String physicalPath)
        {
            var root = HttpContext.Server.MapPath("~");

            var relativePath = physicalPath.Substring(root.Length - 1, physicalPath.Length - root.Length + 1);

            return relativePath.Replace("\\", "/");
        }
    }
}
